package com.itdct.onflow.system.common.handler


import com.itdct.onflow.core.config.OnflowConfig
import com.itdct.onflow.core.constant.ReturnCode
import com.itdct.onflow.core.context.BaseContext
import com.itdct.onflow.core.exception.BaseHandleException
import com.itdct.onflow.core.extend.insertEx
import com.itdct.onflow.core.extend.logError
import com.itdct.onflow.core.util.KBeanCopyUtil
import com.itdct.onflow.core.vo.RespVo
import com.itdct.onflow.system.common.context.Context
import com.itdct.onflow.system.common.exception.DictException
import com.itdct.onflow.system.log.entity.SysImportantApiLogEntity
import com.itdct.onflow.system.log.global.SysApiLogList
import com.itdct.onflow.system.log.mapper.SysApiLogMapper
import com.itdct.onflow.system.log.mapper.SysImportantApiLogMapper
import java.math.BigDecimal
import java.math.RoundingMode
import java.util.*
import java.util.concurrent.ExecutorService

/**
 * @author Zhouwx
 * @date 2025/2/20 16:30:22
 * @version 1.0
 * @description
 */
class SysHandleException(onflowConfig: OnflowConfig, val sysApiLogMapper: SysApiLogMapper, val sysImportantApiLogMapper: SysImportantApiLogMapper, val logThreadPoolExecutor: ExecutorService) :
    BaseHandleException(onflowConfig) {
    override fun handleOtherException(e: Exception): RespVo<*>? {
        if (e is DictException) {
            logError("字典出现问题", e)
            return fail(ReturnCode.DICT_ERROR, e.message)
        } else {
            return null
        }
    }

    override fun failHandleContext(context: BaseContext<*, *>, respVo: RespVo<*>) {
        super.failHandleContext(context, respVo)
        logThreadPoolExecutor.submit {
            if (context is Context) {
                context.sysApiLogEntity?.also {
                    it.responseTime = Date()
                    val totalMs = it.responseTime?.time?.minus(it.requestTime?.time ?: 0) ?: 0
                    it.handleTime = BigDecimal(totalMs).divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP)
                    it.returnCode = context.respVo?.code ?: ReturnCode.UNCAUGHT_SYSTEM_ERROR
                    it.failReason = if (it.returnCode == ReturnCode.SUCCESS) "" else context.respVo?.info ?: ""
                    SysApiLogList.add(it)

                    if (context.apiParamDTO.important) {
                        // INFO: Zhouwx: 2025/9/23 重要接口需要入库
                        val sysImportantApiLogEntity = SysImportantApiLogEntity()
                        KBeanCopyUtil.injectValue(it, sysImportantApiLogEntity, true)
                        sysImportantApiLogEntity.requestBody = context.requestBody
                        sysImportantApiLogEntity.responseBody = context.responseBody
                        sysImportantApiLogMapper.insertEx(sysImportantApiLogEntity)
                    }
                }
            }
        }
    }
}